#ifndef BONDERWORKHOLDER_H
#define BONDERWORKHOLDER_H

#include "AxisModule/singleaxis.h"
#include "AxisModule/xymodule.h"
#include "CompositeElement/sccylinder.h"
#include "Tray/sensortraymap.h"
#include "Tray/sensortraymaterialdata.h"
#include "Tray/trayconfig.h"
#include "VisionLocation/visionlocation.h"
#include "VisionManager/visionmanager.h"
#include "bonderworkholderconfig.h"
#include "namedefinition.h"
#include "postbonddataanalysis.h"
#include "sensortrayconveyer.h"
#include "systemCore/worker.h"
#include "workers/workholderstate.h"

class BonderWorkHolder : public Worker
{
    Q_OBJECT
public:
    BonderWorkHolder(TrayConfig *sensorTrayConfig, WorkHolderState *whState, SensorTrayConveyer *stcWorker);

    BonderWorkHolderConfig *getBwhConfig() const;
    double getBWHOpticYPrPos(int rowIndex);
    PrOffset getSensorPrOffset();
    PrOffset getPostBondOffset();
    bool gotSensor() const;
    void resetGotSensor();
    PrOffset getLastSensorOffset() const;
    QPoint getLastSensorIndex() const;
    void setSensorState(QPoint index, SensorTrayMaterialData::MaterialState state);
    void showPostBondShift(PrOffset shift);
    void savePostBondData(QPoint sensorIndex,
                          QPoint lensIndex,
                          PrOffset &sensorOffset,
                          PrOffset &postBondOffset,
                          bool isValidPostBondOffset,
                          bool result);
    TrayMap *getTrayMap() const;
    PostBondDataAnalysis *getPostBondDataAnalysis() const;
    void correctPostBondShift(PrOffset &shift);

    // Worker interface
protected:
    virtual void initEventHandle() override;
    virtual void startEventHandle(const WorkerEvent &event) override;
    virtual void stopEventHandle() override {}
    virtual void allWorkerStopped() override;
    virtual void purgeEventHandle() override;
    virtual void resetEventHandle() override;
    virtual void homeWorker(bool moveToReadyPosAfterHome) override;

    // 自动运行逻辑
public slots:
    void getNewTray();
    void setSensorTrayMap(QJsonValue data);
    void pushOutTray();
    void getSensor();
    void upOpticZ();
    void postBond(int lensRowIndex, int lensColumnIndex);
    void dispWHStopped();

    // 手动调试操作
public slots:
    void startLoadUnloadTrayLoopTest(int times);
    void stopLoadUnloadTrayLoopTest();
    void resetLoadUnloadTrayLoopTest();
    void manuallyGetNewTray(bool needShotGlue, bool showTip = true);
    void manuallyPushOutTray();
    void cancelManuallyGetNewTray();
    void moveToPrPos(int unitRowIndex, int unitColumnIndex, int rowIndex, int columnIndex);
    void moveToPerformSensorPr(int unitRowIndex, int unitColumnIndex, int rowIndex, int columnIndex);
    void moveToPerformPostBondPr(int unitRowIndex, int unitColumnIndex, int rowIndex, int columnIndex);
    void clearData();
    void downBeltZAndTrackZ();
    void resetRowColumnIndex();

private:
    void upBeltZ(bool moveTrackX);
    void downBeltZ();
    void synchronizeHasTray();
    bool detectReallyHasTray();
    void getNewTrayImpl(bool isManuallyGetTray, bool needLastStationDoneWork = true);
    void pushOutTrayImpl();
    void moveToPrPosImpl(int unitRowIndex, int unitColumnIndex, int rowIndex, int columnIndex);
    void moveToPrPosImpl(int rowIndex, int columnIndex);
    QPointF getPrPos(int unitRowIndex, int unitColumnIndex, int rowIndex, int columnIndex);
    void handleStop();

private:
    TrayConfig *sensorTrayConfig;
    WorkHolderState *whState;
    SensorTrayConveyer *stcWorker;

    TrayMap *sensorTrayMap;

    BonderWorkHolderConfig *bwhConfig;
    ConfigFile *bwhConfigFile;

    PostBondDataAnalysis *postBondDataAnalysis;

    SCCylinder *bonderWHStopperCylLeft;
    SCCylinder *bonderWHStopperCylRight;

    SCDI *bonderWHStageTraySensor;

    SingleAxis *bonderWHBeltZ;
    SingleAxis *bonderWHTrackX;
    SingleAxis *bonderWHTrackZ;
    XYModule *bwhOpticXY;
    SingleAxis *bwhOpticZ;

    SCAxis *bonderWHBelt;

    SCVacuum *bonderWHVacuum;

    VisionLocation *stSensorLocation;
    VisionLocation *postBondLocation;

    SCAxis::Direction beltRunDir;
    bool hasSynchronizeHasTray = false;
    bool hasMoveBeltToCheckHasTrayAtExitOfSTC = false;
    int currentColumnIndex = 0;
    bool m_gotSensor = false;
    PrOffset lastSensorOffset;
    QPoint lastSensorIndex;
    bool isDispWHStopped = false;

    bool hasCancelManuallyGetNewTray = false;
    bool isLoadUnloadTrayLoopTesting = false;

    QString postBondDataFileName;
};

#endif    // BONDERWORKHOLDER_H
